#include "PowerUps.h"

// Initialize the instance to null
PowerUps* PowerUps::m_PowerUpsInstance = 0;

PowerUps::PowerUps(void)
{
}

PowerUps::~PowerUps(void)
{
}

PowerUps* PowerUps::GetInstance(void)
{
	// Create the instance if it doesn't exist
	if(!m_PowerUpsInstance)
		m_PowerUpsInstance = new PowerUps;

	// Return the singleton
	return m_PowerUpsInstance;
}

void PowerUps::DestroyPowerUps(void)
{	
	// Delete the power up list
	for(int i = sPowerCount - 1; i >= 0; i--)
	{
		delete powerUpList[i];
		powerUpList[i] = NULL;
		powerUpList.pop_back();
	}

	// Reset the power up count to 0
	sPowerCount = 0;
}

void PowerUps::DeletePowerInstance(void)
{
	// Delete all the power ups
	PowerUps::ShutdownPowerUps();
	// If instance exist, delete it!
	if(m_PowerUpsInstance)
	{
		delete m_PowerUpsInstance;
		m_PowerUpsInstance = NULL;
	}
}

void PowerUps::InitPowerUps(IDirect3DDevice9* m_pD3DDevice)
{
	// Get the device
	m_Device = m_pD3DDevice;

	// Create the mesh to use for all power ups
	D3DXCreateSphere(m_Device, 0.2f, 50, 50, &m_PowerUpMesh, NULL);
	D3DXCreateSphere(m_Device, 1.5f, 50, 50, &m_MagnetMesh, NULL);

	// Get the instance of the model manager ("PLAYER")
	m_ModelMan = ModelManager::GetInstance();

	// Get the instance of the camera
	m_pCam = Camera::GetInstance();

	// Set the speed for all the power ups
	fSpeed = 6.0f;

	// Wireframe for testing rotation
	//m_Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
	///////////////////////////////////////////////////
	// Set materials for the power ups
	ZeroMemory(&m_PowerMat, sizeof(m_PowerMat));

	m_PowerMat.Ambient.r = 0.0f;
	m_PowerMat.Ambient.g = 0.5f;
	m_PowerMat.Ambient.b = 10.0f;
	m_PowerMat.Diffuse.r = 0.0f;
	m_PowerMat.Diffuse.g = 0.5f;
	m_PowerMat.Diffuse.b = 10.0f;
	m_PowerMat.Specular.r = 0.0f;
	m_PowerMat.Specular.g = 0.5f;
	m_PowerMat.Specular.b = 10.0f;
	m_PowerMat.Emissive.r = 0.0f;
	m_PowerMat.Emissive.g = 0.5f;
	m_PowerMat.Emissive.b = 10.0f;
	m_PowerMat.Power = 50.0f;
	///////////////////////////////////////////////////
}

short PowerUps::CreatePowerUps(short iPowerUpCount)
{
	// Seed the randomizer
	srand((int)timeGetTime());

	// need temporary access to obstacle manager so we can check to see if powerups are spawning inside of an obstacle
	ObstacleManager* obstacleMan = ObstacleManager::GetInstance();
	int iIndex; //temp variable to grab  index count of the Obstacles
	// Set the count to the amount sent in
	sPowerCount = iPowerUpCount;
	sFightPowerUps = 0;
	bool bIsFight = false;
	D3DXVECTOR3 vecPlatPos;
	D3DXVECTOR3 vecFinalPlatPos;
	if(m_ModelMan->GetModelPlaced(3))
	{
		vecPlatPos = m_ModelMan->GetModelPos(3);
		vecFinalPlatPos = m_ModelMan->GetModelPos(14);
		sFightPowerUps = sPowerCount - (sPowerCount / 4);
		bIsFight = true;
	}

	// Boundaries for where they can be created
	sZMax = (short)m_pCam->fZBound - 2;
	sXMin = (short)m_pCam->fXNegBound;
	sXMax = (short)m_pCam->fXBound * 2;

	for(int i = 0; i < sPowerCount; i++)
	{
		// Create the current power up structure we are loading
		s_EnergyPowerUp* currentPowerUp = new s_EnergyPowerUp;

		if(!bIsFight)
		{
			// Set the positions for the power ups
			currentPowerUp->vecPos.x = (float)(rand() % sXMax + sXMin);
			currentPowerUp->vecPos.y = 0.25f;
			currentPowerUp->vecPos.z = (float)(rand() % sZMax + 2);
		}
		else
		{
			if(i < sFightPowerUps)
			{
				// Set the positions for the power ups
				currentPowerUp->vecPos.x = (float)(rand() % sXMax + sXMin);
				currentPowerUp->vecPos.y = 0.25f;
				currentPowerUp->vecPos.z = (float)(rand() % sZMax + 2);
				if(currentPowerUp->vecPos.z >= vecPlatPos.z && currentPowerUp->vecPos.z <= vecFinalPlatPos.z)
					currentPowerUp->vecPos.z = (float)(rand() % (int)vecPlatPos.z + 2);
			}
			else
			{
				currentPowerUp->vecPos.x = (float)(rand() % sXMax + sXMin);
				currentPowerUp->vecPos.y = 10.25f;
				currentPowerUp->vecPos.z = (float)(rand() % (int)(vecFinalPlatPos.z - vecPlatPos.z) + 2) + vecPlatPos.z;
			}
		}

		// Make sure that none of the next power ups are on top of another
		if(i > 0)
		{
			for(int j = 0; j < i; j++)
			{
				if(currentPowerUp->vecPos.x == powerUpList[j]->vecPos.x)
					currentPowerUp->vecPos.x = (float)(rand() % sXMax + sXMin);
			}
		}
		iIndex = obstacleMan->ReturnTeslaIndex();
		if(iIndex > 0) // Make sure we have said obstacle before checking for a spawn collision
		{
			for(int j = 0; j < iIndex; j++)
			{
				// If a powerup spawns inside an obstacle then slightly shift its position out of said obstacle
				if(currentPowerUp->vecPos.x == obstacleMan->teslaList[j]->vecPos.x)
				{
					float fTemp = (float)(rand() % 3 - 1.5);
					currentPowerUp->vecPos.x += fTemp;
				}
			}
		}
		iIndex = obstacleMan->ReturnFirewallIndex();
		if(iIndex > 0)
		{
			for(int j = 0; j < iIndex; j++)
			{
				if(currentPowerUp->vecPos.z == obstacleMan->firewallList[j]->vecPos.z)
				{
					float fTemp = (float)(rand() % 3 - 1.5);
					currentPowerUp->vecPos.z += fTemp;
				}
			}
		}

		// Set the power up to active
		currentPowerUp->bActive = true;

		/////////////////////////////////////////////////////////////////////////////////////
		// MAGNET BOUNDING "BOX"
		// Calculate and create the bounding boxes
		HRESULT hr = 0;
		BYTE* pVertices = 0;
		if( SUCCEEDED(m_MagnetMesh->LockVertexBuffer(0, (void**)&pVertices)))
		{
			// Locking the vertex buffer so we can compute the bounds
			hr = D3DXComputeBoundingBox((D3DXVECTOR3*)pVertices, m_MagnetMesh->GetNumVertices(),
				D3DXGetFVFVertexSize(m_MagnetMesh->GetFVF()), &currentPowerUp->vecMagBBMin, 
				&currentPowerUp->vecMagBBMax);

			// Unlock the vertex buffer
			m_MagnetMesh->UnlockVertexBuffer();

			// With the min and max vectors we can get the 8 corners for the bounding box
			currentPowerUp->vecMagModelBounds[0] = D3DXVECTOR3(currentPowerUp->vecMagBBMin.x, currentPowerUp->vecMagBBMin.y, 
				currentPowerUp->vecMagBBMin.z);
			currentPowerUp->vecMagModelBounds[1] = D3DXVECTOR3(currentPowerUp->vecMagBBMax.x, currentPowerUp->vecMagBBMin.y, 
				currentPowerUp->vecMagBBMin.z);
			currentPowerUp->vecMagModelBounds[2] = D3DXVECTOR3(currentPowerUp->vecMagBBMin.x, currentPowerUp->vecMagBBMax.y, 
				currentPowerUp->vecMagBBMin.z);
			currentPowerUp->vecMagModelBounds[3] = D3DXVECTOR3(currentPowerUp->vecMagBBMax.x, currentPowerUp->vecMagBBMax.y, 
				currentPowerUp->vecMagBBMin.z);
			currentPowerUp->vecMagModelBounds[4] = D3DXVECTOR3(currentPowerUp->vecMagBBMin.x, currentPowerUp->vecMagBBMin.y, 
				currentPowerUp->vecMagBBMax.z);
			currentPowerUp->vecMagModelBounds[5] = D3DXVECTOR3(currentPowerUp->vecMagBBMax.x, currentPowerUp->vecMagBBMin.y, 
				currentPowerUp->vecMagBBMax.z);
			currentPowerUp->vecMagModelBounds[6] = D3DXVECTOR3(currentPowerUp->vecMagBBMin.x, currentPowerUp->vecMagBBMax.y, 
				currentPowerUp->vecMagBBMax.z);
			currentPowerUp->vecMagModelBounds[7] = D3DXVECTOR3(currentPowerUp->vecMagBBMax.x, currentPowerUp->vecMagBBMax.y, 
				currentPowerUp->vecMagBBMax.z);
		}
		/////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////////////////////////////////////////////////////////
		// NORMAL BOUNDING "BOX"
		// Calculate and create the bounding boxes
		if( SUCCEEDED(m_PowerUpMesh->LockVertexBuffer(0, (void**)&pVertices)))
		{
			// Locking the vertex buffer so we can compute the bounds
			hr = D3DXComputeBoundingBox((D3DXVECTOR3*)pVertices, m_PowerUpMesh->GetNumVertices(),
				D3DXGetFVFVertexSize(m_PowerUpMesh->GetFVF()), &currentPowerUp->vecBBMin, 
				&currentPowerUp->vecBBMax);

			// Unlock the vertex buffer
			m_PowerUpMesh->UnlockVertexBuffer();

			// With the min and max vectors we can get the 8 corners for the bounding box
			currentPowerUp->vecModelBounds[0] = D3DXVECTOR3(currentPowerUp->vecBBMin.x, currentPowerUp->vecBBMin.y, 
				currentPowerUp->vecBBMin.z);
			currentPowerUp->vecModelBounds[1] = D3DXVECTOR3(currentPowerUp->vecBBMax.x, currentPowerUp->vecBBMin.y, 
				currentPowerUp->vecBBMin.z);
			currentPowerUp->vecModelBounds[2] = D3DXVECTOR3(currentPowerUp->vecBBMin.x, currentPowerUp->vecBBMax.y, 
				currentPowerUp->vecBBMin.z);
			currentPowerUp->vecModelBounds[3] = D3DXVECTOR3(currentPowerUp->vecBBMax.x, currentPowerUp->vecBBMax.y, 
				currentPowerUp->vecBBMin.z);
			currentPowerUp->vecModelBounds[4] = D3DXVECTOR3(currentPowerUp->vecBBMin.x, currentPowerUp->vecBBMin.y, 
				currentPowerUp->vecBBMax.z);
			currentPowerUp->vecModelBounds[5] = D3DXVECTOR3(currentPowerUp->vecBBMax.x, currentPowerUp->vecBBMin.y, 
				currentPowerUp->vecBBMax.z);
			currentPowerUp->vecModelBounds[6] = D3DXVECTOR3(currentPowerUp->vecBBMin.x, currentPowerUp->vecBBMax.y, 
				currentPowerUp->vecBBMax.z);
			currentPowerUp->vecModelBounds[7] = D3DXVECTOR3(currentPowerUp->vecBBMax.x, currentPowerUp->vecBBMax.y, 
				currentPowerUp->vecBBMax.z);
		}

		// Add the currently loaded power up to the list
		powerUpList.push_back(currentPowerUp);
	}

	return sPowerCount;
}

void PowerUps::UpdatePowerUps(short sCheckpointPower, bool bFightDone)
{
	ObstacleManager* obstacleMan = ObstacleManager::GetInstance();
	int iIndex;
	bool bIsFight = false;
	D3DXVECTOR3 vecPlatPos;
	D3DXVECTOR3 vecFinalPlatPos;
	if(m_ModelMan->GetModelPlaced(3))
	{
		vecPlatPos = m_ModelMan->GetModelPos(3);
		vecFinalPlatPos = m_ModelMan->GetModelPos(14);
		bIsFight = true;
	}
	sPowerCount = sCheckpointPower;

	for(int i = 0; i < sPowerCount; i++)
	{
		// Create the current power up structure we are loading
		s_EnergyPowerUp* currentPowerUp = new s_EnergyPowerUp;

		if(!bIsFight)
		{
			// Set the positions for the power ups
			currentPowerUp->vecPos.x = (float)(rand() % sXMax + sXMin);
			currentPowerUp->vecPos.y = 0.25f;
			currentPowerUp->vecPos.z = (float)(rand() % sZMax + 2);
		}
		else
		{
			if(!bFightDone)
			{
				if(i < sFightPowerUps)
				{
					// Set the positions for the power ups
					currentPowerUp->vecPos.x = (float)(rand() % sXMax + sXMin);
					currentPowerUp->vecPos.y = 0.25f;
					currentPowerUp->vecPos.z = (float)(rand() % sZMax + 2);
				}
				else
				{
					currentPowerUp->vecPos.x = (float)(rand() % sXMax + sXMin);
					currentPowerUp->vecPos.y = 10.25f;
					currentPowerUp->vecPos.z = (float)(rand() % (int)(vecFinalPlatPos.z - vecPlatPos.z) + 2) + vecPlatPos.z;
				}
			}
			else
			{
				currentPowerUp->vecPos.x = (float)(rand() % sXMax + sXMin);
				currentPowerUp->vecPos.y = 0.25f;
				currentPowerUp->vecPos.z = (float)(rand() % sZMax + 2);
			}
		}

		// Make sure that none of the next power ups are on top of another
		if(i > 0)
		{
			for(int j = 0; j < i; j++)
			{
				if(currentPowerUp->vecPos.x == powerUpList[j]->vecPos.x)
					currentPowerUp->vecPos.x = (float)(rand() % sXMax + sXMin);
			}
		}
		iIndex = obstacleMan->ReturnTeslaIndex();
		if(iIndex > 0) // Make sure we have said obstacle before checking for a spawn collision
		{
			for(int j = 0; j < iIndex; j++)
			{
				// If a powerup spawns inside an obstacle then slightly shift its position out of said obstacle
				if(currentPowerUp->vecPos.x == obstacleMan->teslaList[j]->vecPos.x)
				{
					float fTemp = (float)(rand() % 3 - 1.5);
					currentPowerUp->vecPos.x += fTemp;
				}
			}
		}
		iIndex = obstacleMan->ReturnFirewallIndex();
		if(iIndex > 0)
		{
			for(int j = 0; j < iIndex; j++)
			{
				if(currentPowerUp->vecPos.z == obstacleMan->firewallList[j]->vecPos.z)
				{
					float fTemp = (float)(rand() % 3 - 1.5);
					currentPowerUp->vecPos.z += fTemp;
				}
			}
		}

		// Set the power up to active
		currentPowerUp->bActive = true;

		/////////////////////////////////////////////////////////////////////////////////////
		// MAGNET BOUNDING "BOX"
		// Calculate and create the bounding boxes
		HRESULT hr = 0;
		BYTE* pVertices = 0;
		if( SUCCEEDED(m_MagnetMesh->LockVertexBuffer(0, (void**)&pVertices)))
		{
			// Locking the vertex buffer so we can compute the bounds
			hr = D3DXComputeBoundingBox((D3DXVECTOR3*)pVertices, m_MagnetMesh->GetNumVertices(),
				D3DXGetFVFVertexSize(m_MagnetMesh->GetFVF()), &currentPowerUp->vecMagBBMin, 
				&currentPowerUp->vecMagBBMax);

			// Unlock the vertex buffer
			m_MagnetMesh->UnlockVertexBuffer();

			// With the min and max vectors we can get the 8 corners for the bounding box
			currentPowerUp->vecMagModelBounds[0] = D3DXVECTOR3(currentPowerUp->vecMagBBMin.x, currentPowerUp->vecMagBBMin.y, 
				currentPowerUp->vecMagBBMin.z);
			currentPowerUp->vecMagModelBounds[1] = D3DXVECTOR3(currentPowerUp->vecMagBBMax.x, currentPowerUp->vecMagBBMin.y, 
				currentPowerUp->vecMagBBMin.z);
			currentPowerUp->vecMagModelBounds[2] = D3DXVECTOR3(currentPowerUp->vecMagBBMin.x, currentPowerUp->vecMagBBMax.y, 
				currentPowerUp->vecMagBBMin.z);
			currentPowerUp->vecMagModelBounds[3] = D3DXVECTOR3(currentPowerUp->vecMagBBMax.x, currentPowerUp->vecMagBBMax.y, 
				currentPowerUp->vecMagBBMin.z);
			currentPowerUp->vecMagModelBounds[4] = D3DXVECTOR3(currentPowerUp->vecMagBBMin.x, currentPowerUp->vecMagBBMin.y, 
				currentPowerUp->vecMagBBMax.z);
			currentPowerUp->vecMagModelBounds[5] = D3DXVECTOR3(currentPowerUp->vecMagBBMax.x, currentPowerUp->vecMagBBMin.y, 
				currentPowerUp->vecMagBBMax.z);
			currentPowerUp->vecMagModelBounds[6] = D3DXVECTOR3(currentPowerUp->vecMagBBMin.x, currentPowerUp->vecMagBBMax.y, 
				currentPowerUp->vecMagBBMax.z);
			currentPowerUp->vecMagModelBounds[7] = D3DXVECTOR3(currentPowerUp->vecMagBBMax.x, currentPowerUp->vecMagBBMax.y, 
				currentPowerUp->vecMagBBMax.z);
		}
		/////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////////////////////////////////////////////////////////
		// NORMAL BOUNDING "BOX"
		// Calculate and create the bounding boxes
		if( SUCCEEDED(m_PowerUpMesh->LockVertexBuffer(0, (void**)&pVertices)))
		{
			// Locking the vertex buffer so we can compute the bounds
			hr = D3DXComputeBoundingBox((D3DXVECTOR3*)pVertices, m_PowerUpMesh->GetNumVertices(),
				D3DXGetFVFVertexSize(m_PowerUpMesh->GetFVF()), &currentPowerUp->vecBBMin, 
				&currentPowerUp->vecBBMax);

			// Unlock the vertex buffer
			m_PowerUpMesh->UnlockVertexBuffer();

			// With the min and max vectors we can get the 8 corners for the bounding box
			currentPowerUp->vecModelBounds[0] = D3DXVECTOR3(currentPowerUp->vecBBMin.x, currentPowerUp->vecBBMin.y, 
				currentPowerUp->vecBBMin.z);
			currentPowerUp->vecModelBounds[1] = D3DXVECTOR3(currentPowerUp->vecBBMax.x, currentPowerUp->vecBBMin.y, 
				currentPowerUp->vecBBMin.z);
			currentPowerUp->vecModelBounds[2] = D3DXVECTOR3(currentPowerUp->vecBBMin.x, currentPowerUp->vecBBMax.y, 
				currentPowerUp->vecBBMin.z);
			currentPowerUp->vecModelBounds[3] = D3DXVECTOR3(currentPowerUp->vecBBMax.x, currentPowerUp->vecBBMax.y, 
				currentPowerUp->vecBBMin.z);
			currentPowerUp->vecModelBounds[4] = D3DXVECTOR3(currentPowerUp->vecBBMin.x, currentPowerUp->vecBBMin.y, 
				currentPowerUp->vecBBMax.z);
			currentPowerUp->vecModelBounds[5] = D3DXVECTOR3(currentPowerUp->vecBBMax.x, currentPowerUp->vecBBMin.y, 
				currentPowerUp->vecBBMax.z);
			currentPowerUp->vecModelBounds[6] = D3DXVECTOR3(currentPowerUp->vecBBMin.x, currentPowerUp->vecBBMax.y, 
				currentPowerUp->vecBBMax.z);
			currentPowerUp->vecModelBounds[7] = D3DXVECTOR3(currentPowerUp->vecBBMax.x, currentPowerUp->vecBBMax.y, 
				currentPowerUp->vecBBMax.z);
		}

		// Add the currently loaded power up to the list
		powerUpList.push_back(currentPowerUp);
	}
}

void PowerUps::StartPull(int iPowerID, float fDeltaTime)
{
	// Get the player position to start moving towards him
	D3DXVECTOR3 &vecPlayerPos = m_ModelMan->GetPlayerPos();

	// Calculate the distance between the player and power up
	vecDistance.x = vecPlayerPos.x - powerUpList[iPowerID]->vecPos.x;
	vecDistance.y = vecPlayerPos.y - powerUpList[iPowerID]->vecPos.y;
	vecDistance.z = vecPlayerPos.z - powerUpList[iPowerID]->vecPos.z;

	// Normalize the distance vector
	//D3DXVec3Normalize(&vecDistance, &vecDistance);

	// Start adding the direction vector to the power up to move
	// it towards the player
	powerUpList[iPowerID]->vecPos.x += vecDistance.x * fSpeed * fDeltaTime;
	powerUpList[iPowerID]->vecPos.y += vecDistance.y * fSpeed * fDeltaTime;
	powerUpList[iPowerID]->vecPos.z += vecDistance.z * fSpeed * fDeltaTime;
}

void PowerUps::RenderPowerUps(void)
{
	for(int i = 0; i < sPowerCount; i++)
	{
		if(powerUpList[i]->bActive)
		{
			// Reset the matrices
			D3DXMatrixIdentity(&powerUpList[i]->scaleMat);
			D3DXMatrixIdentity(&powerUpList[i]->rotMat);
			D3DXMatrixIdentity(&powerUpList[i]->transMat);
			D3DXMatrixIdentity(&powerUpList[i]->worldMat);

			// Rotate, scale, and move the power up
			D3DXMatrixScaling(&powerUpList[i]->scaleMat, 1.0f, 1.0f, 1.0f);
			D3DXMatrixRotationY(&powerUpList[i]->rotMat, timeGetTime() / -100.0f);
			D3DXMatrixTranslation(&powerUpList[i]->transMat, powerUpList[i]->vecPos.x, powerUpList[i]->vecPos.y, powerUpList[i]->vecPos.z);

			// Scale & rotation * translation
			D3DXMatrixMultiply(&powerUpList[i]->scaleMat, &powerUpList[i]->rotMat, &powerUpList[i]->scaleMat);
			D3DXMatrixMultiply(&powerUpList[i]->worldMat, &powerUpList[i]->scaleMat, &powerUpList[i]->transMat);

			// Set the transform
			m_Device->SetTransform(D3DTS_WORLD, &powerUpList[i]->worldMat);

			// Set material to the power up
			m_Device->SetMaterial(&m_PowerMat);
			// Draw the mesh
			m_PowerUpMesh->DrawSubset(0);

			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			//		Testing code!!!!      Drawing Bounding Box to ensure it is correcly placed on model
			//// Turning on Wireframe
			//m_Device->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );

			//// get attributes to draw bounding box
			//float width, height, depth;
			///*width = (powerUpList[i]->vecBBMax.x) - (powerUpList[i]->vecBBMin.x);
			//height = (powerUpList[i]->vecBBMax.y) - (powerUpList[i]->vecBBMin.y);
			//depth = (powerUpList[i]->vecBBMax.z) - (powerUpList[i]->vecBBMin.z);*/

			//// Testing for magnet box
			//width = (powerUpList[i]->vecMagBBMax.x) - (powerUpList[i]->vecMagBBMin.x);
			//height = (powerUpList[i]->vecMagBBMax.y) - (powerUpList[i]->vecMagBBMin.y);
			//depth = (powerUpList[i]->vecMagBBMax.z) - (powerUpList[i]->vecMagBBMin.z);

			//// Make a mesh
			//D3DXCreateBox( m_Device, width, height, depth, &m_BBMesh, NULL);
			//// Draw box
			//m_BBMesh->DrawSubset(0);

			//// Turn off WireFrame
			//m_Device->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		}
	}
}

void PowerUps::CalculateWorldBB(int iPowerID)
{
	// Convert Object's model space bounding box to world space
	// Transform the 8 corners of our object space bounding box into world space
	D3DXVECTOR3 worldBounds[8];
	for( int i = 0; i < 8; i++)
		D3DXVec3TransformCoord( &worldBounds[i], &powerUpList[iPowerID]->vecModelBounds[i], &powerUpList[iPowerID]->worldMat );

	// Pick a corner and set the smallest point and largest point to that corner
	powerUpList[iPowerID]->worldBBmin = worldBounds[0];
	powerUpList[iPowerID]->worldBBmax = worldBounds[0];

	// Find the new minimum and maximum points after transformation
	// Now, compare the other corners and see if they are smaller or larger
	for( short i = 1; i < 8; i++ )
	{
		if(worldBounds[i].x < powerUpList[iPowerID]->worldBBmin.x)
			powerUpList[iPowerID]->worldBBmin.x = worldBounds[i].x;
		if(worldBounds[i].x > powerUpList[iPowerID]->worldBBmax.x)
			powerUpList[iPowerID]->worldBBmax.x = worldBounds[i].x;
		if(worldBounds[i].y < powerUpList[iPowerID]->worldBBmin.y)
			powerUpList[iPowerID]->worldBBmin.y = worldBounds[i].y;
		if(worldBounds[i].y > powerUpList[iPowerID]->worldBBmax.y)
			powerUpList[iPowerID]->worldBBmax.y = worldBounds[i].y;
		if(worldBounds[i].z < powerUpList[iPowerID]->worldBBmin.z)
			powerUpList[iPowerID]->worldBBmin.z = worldBounds[i].z;
		if(worldBounds[i].z > powerUpList[iPowerID]->worldBBmax.z)
			powerUpList[iPowerID]->worldBBmax.z = worldBounds[i].z;	
	}
}

void PowerUps::CalculateMagnetWorldBB(int iPowerID)
{
	// Convert Object's model space bounding box to world space
	// Transform the 8 corners of our object space bounding box into world space
	D3DXVECTOR3 worldBounds[8];
	for( int i = 0; i < 8; i++)
		D3DXVec3TransformCoord( &worldBounds[i], &powerUpList[iPowerID]->vecMagModelBounds[i], &powerUpList[iPowerID]->worldMat );

	// Pick a corner and set the smallest point and largest point to that corner
	powerUpList[iPowerID]->worldMagBBmin = worldBounds[0];
	powerUpList[iPowerID]->worldMagBBmax = worldBounds[0];

	// Find the new minimum and maximum points after transformation
	// Now, compare the other corners and see if they are smaller or larger
	for( short i = 1; i < 8; i++ )
	{
		if(worldBounds[i].x < powerUpList[iPowerID]->worldMagBBmin.x)
			powerUpList[iPowerID]->worldMagBBmin.x = worldBounds[i].x;
		if(worldBounds[i].x > powerUpList[iPowerID]->worldMagBBmax.x)
			powerUpList[iPowerID]->worldMagBBmax.x = worldBounds[i].x;
		if(worldBounds[i].y < powerUpList[iPowerID]->worldMagBBmin.y)
			powerUpList[iPowerID]->worldMagBBmin.y = worldBounds[i].y;
		if(worldBounds[i].y > powerUpList[iPowerID]->worldMagBBmax.y)
			powerUpList[iPowerID]->worldMagBBmax.y = worldBounds[i].y;
		if(worldBounds[i].z < powerUpList[iPowerID]->worldMagBBmin.z)
			powerUpList[iPowerID]->worldMagBBmin.z = worldBounds[i].z;
		if(worldBounds[i].z > powerUpList[iPowerID]->worldMagBBmax.z)
			powerUpList[iPowerID]->worldMagBBmax.z = worldBounds[i].z;	
	}
}

bool PowerUps::CollisionDetection(int iPowerID)
{
	if(powerUpList[iPowerID]->bActive)
	{
		// Calculate the world space bounding box for player object
		m_ModelMan->CalculateWorldBB(0);

		// Calculate the world space bounding box for power up object
		CalculateWorldBB(iPowerID);

		// Collision check on the boundaries
		if(m_ModelMan->modelList[0]->worldBBmax.x < powerUpList[iPowerID]->worldBBmin.x)
			return false;
		if(m_ModelMan->modelList[0]->worldBBmax.y < powerUpList[iPowerID]->worldBBmin.y)
			return false;
		if(m_ModelMan->modelList[0]->worldBBmax.z < powerUpList[iPowerID]->worldBBmin.z)
			return false;
		if(m_ModelMan->modelList[0]->worldBBmin.x > powerUpList[iPowerID]->worldBBmax.x)
			return false;
		if(m_ModelMan->modelList[0]->worldBBmin.y > powerUpList[iPowerID]->worldBBmax.y)
			return false;
		if(m_ModelMan->modelList[0]->worldBBmin.z > powerUpList[iPowerID]->worldBBmax.z)
			return false;

		// Collision occured
		powerUpList[iPowerID]->bActive = false;
		return true;
	}
	// No collision occured
	return false;
}

bool PowerUps::MagnetCollisionDetection(int iPowerID)
{
	if(powerUpList[iPowerID]->bActive)
	{
		// Calculate the world space bounding box for player object
		m_ModelMan->CalculateWorldBB(0);

		// Calculate the world space bounding box for power up object
		CalculateMagnetWorldBB(iPowerID);

		// Collision check on the boundaries
		if(m_ModelMan->modelList[0]->worldBBmax.x < powerUpList[iPowerID]->worldMagBBmin.x)
			return false;
		if(m_ModelMan->modelList[0]->worldBBmax.y < powerUpList[iPowerID]->worldMagBBmin.y)
			return false;
		if(m_ModelMan->modelList[0]->worldBBmax.z < powerUpList[iPowerID]->worldMagBBmin.z)
			return false;
		if(m_ModelMan->modelList[0]->worldBBmin.x > powerUpList[iPowerID]->worldMagBBmax.x)
			return false;
		if(m_ModelMan->modelList[0]->worldBBmin.y > powerUpList[iPowerID]->worldMagBBmax.y)
			return false;
		if(m_ModelMan->modelList[0]->worldBBmin.z > powerUpList[iPowerID]->worldMagBBmax.z)
			return false;

		// Collision occured
		return true;
	}
	else
		return false;
}

void PowerUps::ShutdownPowerUps(void)
{
	// Delete the power up list
	for(int i = 0; i < sPowerCount; i++)
	{
		delete powerUpList[i];
		powerUpList[i] = NULL;
	}

	// Reset the power up count to 0
	sPowerCount = 0;

	// Release the mesh object
	if(m_PowerUpMesh)
	{
		m_PowerUpMesh->Release();
		m_PowerUpMesh = NULL;
	}
}